package com.ruoyi.web.core.service;

import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.web.core.config.WxPayConfig;
import com.ruoyi.fun.domain.SysWechatConfig;
import com.ruoyi.fun.service.ISysWechatConfigService;
import com.ruoyi.fun.service.IEcOrderService;
import com.ruoyi.fun.service.IEcOrderItemService;
import com.ruoyi.fun.service.IEcProductService;
import com.ruoyi.fun.service.IEcProductSkuService;
import com.ruoyi.fun.domain.EcOrder;
import com.ruoyi.fun.domain.EcOrderItem;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.exception.HttpException;
import com.wechat.pay.java.core.exception.MalformedMessageException;
import com.wechat.pay.java.core.exception.ServiceException;
import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension;
import com.wechat.pay.java.service.payments.jsapi.model.*;
import com.wechat.pay.java.service.payments.jsapi.model.QueryOrderByOutTradeNoRequest;
import com.wechat.pay.java.service.payments.model.Transaction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;

/**
 * 微信支付服务类
 * 
 * @author ruoyi
 */
@Service
public class WxPayService {
    
    private static final Logger log = LoggerFactory.getLogger(WxPayService.class);
    
    @Autowired
    private WxPayConfig wxPayConfig;
    
    @Autowired
    private IEcOrderService ecOrderService;
    
    @Autowired
    private IEcOrderItemService ecOrderItemService;
    
    @Autowired
    private IEcProductService ecProductService;
    
    @Autowired
    private IEcProductSkuService ecProductSkuService;

    @Autowired
    private ISysWechatConfigService sysWechatConfigService;

    @Autowired
    private MerchantKeyCache merchantKeyCache;
    
    /**
     * 创建预支付订单
     * 
     * @param orderNo 订单号
     * @param description 商品描述
     * @param amount 支付金额（元）
     * @param openId 用户openId
     * @param appId 微信应用ID
     * @param merchantId 商户号
     * @param privateKey 商户API私钥
     * @param merchantSerialNumber 商户证书序列号
     * @param apiV3Key 商户APIv3密钥
     * @param notifyUrl 支付回调地址
     * @return 预支付响应
     */
    public PrepayWithRequestPaymentResponse createPrepayOrder(String orderNo, String description, BigDecimal amount, String openId,
                                                             String wechatAppId, String orgId, String notifyUrl) {
        log.info("=== WxPayService：开始创建预支付订单 ===");
        log.info("接收到的参数 - 订单号: {}", orderNo);
        log.info("接收到的参数 - 描述: {}", description);
        log.info("接收到的参数 - 金额: {}", amount);
        log.info("接收到的参数 - openId: {}", openId);
        log.info("接收到的参数 - openId类型: {}", openId != null ? openId.getClass().getSimpleName() : "null");
        log.info("接收到的参数 - openId长度: {}", openId != null ? openId.length() : 0);
        log.info("接收到的参数 - openId是否为空: {}", openId == null || openId.trim().isEmpty());
        log.info("接收到的参数 - wechatAppId: {}", wechatAppId);
        log.info("接收到的参数 - orgId: {}", orgId);
        
        if (openId == null || openId.trim().isEmpty()) {
            log.error("❌ openId参数为空，无法创建预支付订单");
            throw new RuntimeException("用户openId不能为空");
        }
        
        try {
            // 读取商户配置（按 orgId + wechatAppId）
            SysWechatConfig wechatConfig = sysWechatConfigService.selectByOrgIdAndAppId(orgId, wechatAppId);
            if (wechatConfig == null) {
                log.error("未找到微信支付配置，orgId={}, appId={}", orgId, wechatAppId);
                throw new RuntimeException("微信支付配置不存在，请联系管理员");
            }

            String merchantId = wechatConfig.getMchId();
            String merchantSerialNumber = wechatConfig.getApiMchKey();
            String apiV3Key = wechatConfig.getApiV3Key();
            String keyUrl = wechatConfig.getPayApiclientKey();

            if (merchantId == null || merchantSerialNumber == null || apiV3Key == null || keyUrl == null) {
                throw new RuntimeException("微信支付配置不完整，请补全商户号/证书序列号/APIv3密钥/私钥URL");
            }

            // 从缓存或对象存储拉取私钥（PEM 内容）
            String privateKey = merchantKeyCache.getOrFetchPrivateKey(orgId, wechatAppId, keyUrl);

            // 创建动态配置
            RSAAutoCertificateConfig config = new RSAAutoCertificateConfig.Builder()
                    .merchantId(merchantId)
                    .privateKey(privateKey)
                    .merchantSerialNumber(merchantSerialNumber)
                    .apiV3Key(apiV3Key)
                    .build();
            
            // 创建JSAPI服务
            JsapiServiceExtension service = new JsapiServiceExtension.Builder()
                    .config(config)
                    .signType("RSA")
                    .build();
            
            // 构建预支付请求
            PrepayRequest request = new PrepayRequest();
            request.setAppid(wechatAppId);
            request.setMchid(merchantId);
            request.setDescription(description);
            request.setOutTradeNo(orderNo);
            request.setNotifyUrl(notifyUrl);
            
            // 设置金额（微信支付金额单位为分）
            Amount amountObj = new Amount();
            amountObj.setTotal(amount.multiply(new BigDecimal("100")).intValue());
            amountObj.setCurrency("CNY");
            request.setAmount(amountObj);
            
            // 设置支付者信息
            log.info("=== 设置支付者信息 ===");
            log.info("准备设置的openId: {}", openId);
            Payer payer = new Payer();
            payer.setOpenid(openId);
            log.info("Payer对象设置完成，openId: {}", payer.getOpenid());
            request.setPayer(payer);
            log.info("PrepayRequest设置完成，Payer中的openId: {}", request.getPayer().getOpenid());
            
            log.info("请求预支付下单，订单号：{}，金额：{}元，请求参数：{}", orderNo, amount, JSONObject.toJSONString(request));
            
            // 调用预支付接口
            PrepayWithRequestPaymentResponse response = service.prepayWithRequestPayment(request);
            
            log.info("订单【{}】发起预支付成功，返回信息：{}", orderNo, JSONObject.toJSONString(response));
            
            return response;
            
        } catch (HttpException e) {
            log.error("微信下单发送HTTP请求失败，订单号：{}，错误信息：{}", orderNo, e.getHttpRequest());
            throw new RuntimeException("微信支付下单失败：HTTP请求异常");
        } catch (ServiceException e) {
            log.error("微信下单服务状态错误，订单号：{}，错误信息：{}", orderNo, e.getErrorMessage());
            throw new RuntimeException("微信支付下单失败：" + e.getErrorMessage());
        } catch (MalformedMessageException e) {
            log.error("微信下单返回体解析失败，订单号：{}，错误信息：{}", orderNo, e.getMessage());
            throw new RuntimeException("微信支付下单失败：返回数据解析异常");
        } catch (Exception e) {
            log.error("微信下单发生未知异常，订单号：{}，错误信息：{}", orderNo, e.getMessage(), e);
            throw new RuntimeException("微信支付下单失败：系统异常");
        }
    }
    
    /**
     * 处理支付回调通知
     * 
     * @param requestBody 回调请求体
     * @param signature 签名
     * @param nonce 随机字符串
     * @param timestamp 时间戳
     * @param serial 证书序列号
     * @param signType 签名类型
     * @return 处理结果
     */
    public boolean handlePayNotify(String requestBody, String signature, String nonce, String timestamp, String serial, String signType) {
        try {
            log.info("收到微信支付回调通知，请求体：{}", requestBody);
            
            // 解析回调数据
            JSONObject callbackData = JSONObject.parseObject(requestBody);
            String eventType = callbackData.getString("event_type");
            
            // 只处理支付成功的回调
            if ("TRANSACTION.SUCCESS".equals(eventType)) {
                JSONObject resource = callbackData.getJSONObject("resource");
                if (resource != null) {
                    // 这里应该解密resource中的数据，简化处理直接获取订单号
                    // 实际项目中需要按照微信支付文档进行解密
                    String outTradeNo = extractOrderNoFromCallback(requestBody);
                    
                    if (outTradeNo != null) {
                        log.info("支付成功，订单号：{}", outTradeNo);
                        
                        // 更新订单状态为已支付
                        updateOrderPaymentStatus(outTradeNo);
                        
                        // 注释掉销量更新逻辑，避免与AppOrderController中的更新重复
                        // 销量更新将在AppOrderController的updateOrderStatus方法中处理
                        // updateProductSaleCount(outTradeNo);
                    }
                }
            }
            
            log.info("微信支付回调处理成功");
            return true;
            
        } catch (Exception e) {
            log.error("处理微信支付回调失败，错误信息：{}", e.getMessage(), e);
            return false;
        }
    }
    
    /**
     * 从回调数据中提取订单号（简化实现）
     * 实际项目中需要按照微信支付文档进行解密
     */
    private String extractOrderNoFromCallback(String requestBody) {
        try {
            // 这里是简化实现，实际需要解密resource字段
            // 临时方案：从请求体中查找订单号模式
            if (requestBody.contains("out_trade_no")) {
                // 使用正则表达式提取订单号
                java.util.regex.Pattern pattern = java.util.regex.Pattern.compile("\"out_trade_no\":\"([^\"]+)\"");
                java.util.regex.Matcher matcher = pattern.matcher(requestBody);
                if (matcher.find()) {
                    return matcher.group(1);
                }
            }
            return null;
        } catch (Exception e) {
            log.error("提取订单号失败：{}", e.getMessage());
            return null;
        }
    }
    
    /**
     * 更新订单支付状态
     */
    private void updateOrderPaymentStatus(String orderNo) {
        try {
            EcOrder queryOrder = new EcOrder();
            queryOrder.setOrderNo(orderNo);
            List<EcOrder> orderList = ecOrderService.selectEcOrderList(queryOrder);
            
            if (orderList != null && !orderList.isEmpty()) {
                EcOrder order = orderList.get(0);
                order.setPaymentStatus("1"); // 设置为已支付
                order.setOrderStatus("2"); // 设置订单状态为待发货
                ecOrderService.updateEcOrder(order);
                log.info("订单支付状态更新成功，订单号：{}", orderNo);
            }
        } catch (Exception e) {
            log.error("更新订单支付状态失败，订单号：{}，错误：{}", orderNo, e.getMessage());
        }
    }
    
    /**
     * 更新商品销量
     */
    private void updateProductSaleCount(String orderNo) {
        try {
            System.out.println("\n=== 微信支付回调：开始更新销量 ===");
            System.out.println("订单号: " + orderNo);
            
            // 根据订单号查询订单信息获取orgId
            EcOrder orderQuery = new EcOrder();
            orderQuery.setOrderNo(orderNo);
            List<EcOrder> orderList = ecOrderService.selectEcOrderList(orderQuery);
            Long orgId = null;
            if (orderList != null && !orderList.isEmpty()) {
                orgId = orderList.get(0).getOrgId();
                System.out.println("查询到订单组织ID: " + orgId);
            } else {
                System.out.println("警告：未找到订单信息！");
            }
            
            // 根据订单号查询订单商品列表
            EcOrderItem queryItem = new EcOrderItem();
            queryItem.setOrderNo(orderNo);
            List<EcOrderItem> itemList = ecOrderItemService.selectEcOrderItemList(queryItem);
            
            if (itemList != null && !itemList.isEmpty()) {
                System.out.println("找到订单商品项数量: " + itemList.size());
                for (EcOrderItem item : itemList) {
                    System.out.println("\n--- 处理商品项 ---");
                    System.out.println("商品ID: " + item.getProductId());
                    System.out.println("SKU ID: " + item.getSkuId());
                    System.out.println("购买数量: " + item.getProductQuantity());
                    
                    if (item.getProductId() != null && item.getProductQuantity() != null) {
                        // 更新商品销量，增加购买数量
                        ecProductService.updateProductSaleCount(item.getProductId(), item.getProductQuantity().intValue());
                        log.info("商品销量更新成功，商品ID：{}，增加数量：{}", item.getProductId(), item.getProductQuantity());
                        
                        // 同时更新SKU销量（如果有SKU ID）- 注释掉避免重复调用
                        // if (item.getSkuId() != null && orgId != null) {
                        //     System.out.println("开始更新SKU销量...");
                        //     int skuResult = ecProductSkuService.updateSkuSaleCount(item.getSkuId(), item.getProductQuantity().intValue(), orgId);
                        //     System.out.println("SKU销量更新返回结果: " + skuResult);
                        //     log.info("SKU销量更新成功，SKU ID：{}，增加数量：{}，组织ID：{}", item.getSkuId(), item.getProductQuantity(), orgId);
                        // } else {
                        //     System.out.println("跳过SKU销量更新 - SKU ID: " + item.getSkuId() + ", 组织ID: " + orgId);
                        // }
                    }
                }
            } else {
                System.out.println("警告：未找到订单商品项！");
            }
            System.out.println("=== 微信支付回调：销量更新完成 ===\n");
        } catch (Exception e) {
            System.out.println("更新销量异常: " + e.getMessage());
            e.printStackTrace();
            log.error("更新商品销量失败，订单号：{}，错误：{}", orderNo, e.getMessage());
        }
    }
    
    /**
     * 查询订单支付状态
     * 
     * @param orderNo 订单号
     * @param merchantId 商户号
     * @param privateKey 商户API私钥
     * @param merchantSerialNumber 商户证书序列号
     * @param apiV3Key 商户APIv3密钥
     * @return 查询结果
     */
    public JSONObject queryOrderStatus(String orderNo, String orgId, String wechatAppId) {
        try {
            // 读取商户配置
            SysWechatConfig wechatConfig = sysWechatConfigService.selectByOrgIdAndAppId(orgId, wechatAppId);
            if (wechatConfig == null) {
                throw new RuntimeException("微信支付配置不存在");
            }
            String merchantId = wechatConfig.getMchId();
            String merchantSerialNumber = wechatConfig.getApiMchKey();
            String apiV3Key = wechatConfig.getApiV3Key();
            String keyUrl = wechatConfig.getPayApiclientKey();
            String privateKey = merchantKeyCache.getOrFetchPrivateKey(orgId, wechatAppId, keyUrl);

            // 创建动态配置
            RSAAutoCertificateConfig config = new RSAAutoCertificateConfig.Builder()
                    .merchantId(merchantId)
                    .privateKey(privateKey)
                    .merchantSerialNumber(merchantSerialNumber)
                    .apiV3Key(apiV3Key)
                    .build();
            
            // 创建JSAPI服务
            JsapiServiceExtension service = new JsapiServiceExtension.Builder()
                    .config(config)
                    .signType("RSA")
                    .build();
            
            // 查询订单
            QueryOrderByOutTradeNoRequest queryRequest = new QueryOrderByOutTradeNoRequest();
            queryRequest.setMchid(merchantId);
            queryRequest.setOutTradeNo(orderNo);
            
            log.info("查询订单支付状态，订单号：{}", orderNo);
            
            // 调用微信支付查询接口
            Transaction transaction = service.queryOrderByOutTradeNo(queryRequest);
            
            // 构建返回结果
            JSONObject result = new JSONObject();
            result.put("orderNo", orderNo);
            result.put("transactionId", transaction.getTransactionId());
            result.put("tradeState", transaction.getTradeState());
            result.put("tradeStateDesc", transaction.getTradeStateDesc());
            result.put("successTime", transaction.getSuccessTime());
            
            if (transaction.getAmount() != null) {
                result.put("totalAmount", transaction.getAmount().getTotal());
                result.put("payerAmount", transaction.getAmount().getPayerTotal());
            }
            
            return result;
            
        } catch (Exception e) {
            log.error("查询订单支付状态失败，订单号：{}，错误信息：{}", orderNo, e.getMessage(), e);
            throw new RuntimeException("查询订单状态失败");
        }
    }

    /**
     * 提供商户公开信息
     */
    public JSONObject getMerchantPublicInfo(String orgId, String wechatAppId) {
        SysWechatConfig wechatConfig = sysWechatConfigService.selectByOrgIdAndAppId(orgId, wechatAppId);
        if (wechatConfig == null) {
            throw new RuntimeException("微信配置不存在");
        }
        JSONObject obj = new JSONObject();
        obj.put("merchantId", wechatConfig.getMchId());
        obj.put("orgId", wechatConfig.getOrgId());
        obj.put("wechatAppId", wechatConfig.getWechatAppid());
        return obj;
    }
}
